package com.zmh.service.httpclient;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.zmh.dao.BookDao;
import com.zmh.dao.CatalogDao;
import com.zmh.model.book.BookInfo;
import com.zmh.model.book.CatalogInfo;

/**
 * @author zhoumh
 * @version 创建时间：2017年7月19日 下午4:31:12
 * @Description
 */
@Service
public class QiDian {
	private static Logger logger = LoggerFactory.getLogger(QiDian.class);
	@Autowired
	private BookDao bookDao;
	@Autowired
	private CatalogDao catalogDao;
	static CloseableHttpClient httpClient = null;
	static RequestConfig requestConfig = null;
	static Map<String, String> cookieMap = new HashMap<String, String>(64);
	/**
	 * 根据书籍URL获取书籍信息和目录信息并保存到数据库
	 * @author zhoumh
	 * @version 创建时间：2017年9月20日 下午2:53:20
	 */
	public void getQiDian() {
		List<BookInfo> books = getAllBook();
		for (BookInfo bookInfo : books) {
			String url = bookInfo.getUrl();
			//如果不是起点的书籍
			if (url.indexOf("qidian")<0) {
				continue;
			}
			String html = getHTML(url); // 获取书籍信息
			bookInfo.setUrl(url);
			bookInfo.setCatalog(url + "#Catalog");
//		addBook(html, book); // 保存书籍信息
			updateBook(html, bookInfo);
//			bookInfo = bookDao.queryBookByUrl(url);
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookInfo.getUuid());
			html = getHTML(url + "#Catalog"); // 获取目录信息
//		addCatalog(html, catalogInfo);
		}
	}
	
	
	private List<BookInfo> getAllBook(){
		List<BookInfo> books = bookDao.queryBookByAll();
		return books;
	}
	/**
	 * 从起点的书籍页面获取书籍信息并添加到数据库
	 * @param url 起点中文的书籍页面地址
	 * @return: boolean 添加书籍信息是否成功
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午11:25:42 
	 * @Description:
	 */
	public boolean addBookByUrl(String url) {
		boolean result = true;
		BookInfo bookInfo = new BookInfo();
		String html = getHTML(url); // 获取书籍信息
		bookInfo.setUrl(url);
		bookInfo.setCatalog(url + "#Catalog");
		// 对返回的书架内容做解析，将每本书的名称地址信息提取出来
		Document doc = Jsoup.parse(html);
		// 解析书籍信息
		bookInfo.setName(doc.select("div.book-info > h1 > em").text());
		bookInfo.setAuthor(doc.select("div.book-info > h1 > span > a").text());
		bookInfo.setDetail(doc.select("div.book-intro > p").text().trim().replaceAll("　", ""));
		bookInfo.setCover("http:" + doc.select("div.book-img > a > img").attr("src"));
		logger.info(JSON.toJSONString(bookInfo));
		if (bookDao.insertBook(bookInfo)!=1) {
			//如果返回值不为1就说明增加失败
			result = false;
		}
		return result;
	}
	
	/**
	 * 解析网页并增加书籍信息
	 * @author zhoumh
	 * @version 创建时间：2017年8月29日 下午5:26:07
	 */
	private void addBook(String html, BookInfo book) {
		// 对返回的书架内容做解析，将每本书的名称地址信息提取出来
		Document doc = Jsoup.parse(html);
		// 设置书名
		book.setName(doc.select("div.book-info > h1 > em").text());
		book.setAuthor(doc.select("div.book-info > h1 > span > a").text());
		book.setDetail(doc.select("div.book-intro > p").text().trim().replaceAll("　", ""));
		book.setCover("http:" + doc.select("div.book-img > a > img").attr("src"));
		bookDao.insertBook(book);
//		System.out.println(JSON.toJSONString(book));
	}
	
	/**
	 * 修改书籍信息
	 * @author zhoumh
	 * @version 创建时间：2017年8月29日 下午5:26:07
	 */
	private void updateBook(String html, BookInfo book) {
		// 对返回的书架内容做解析，将每本书的名称地址信息提取出来
		Document doc = Jsoup.parse(html);
		// 设置书名
		book.setName(doc.select("div.book-info > h1 > em").text());
		book.setAuthor(doc.select("div.book-info > h1 > span > a").text());
		book.setDetail(doc.select("div.book-intro > p").text().trim().replaceAll("　", ""));
		book.setCover("http:" + doc.select("div.book-img > a > img").attr("src"));
		bookDao.updateBook(book);
		System.out.println(JSON.toJSONString(book));
	}
	/**
	 * 增加章节目录信息
	 * @author zhoumh
	 * @version 创建时间：2017年9月20日 下午3:13:53
	 */
	private void addCatalog(String html, CatalogInfo catalogInfo) {
		Document doc = Jsoup.parse(html);
		Elements elements = doc.select("div.volume-wrap > div.volume > ul.cf > li");
		int i = 1;
		for (Element element : elements) {
			catalogInfo.setName(element.select("a").text());
			String title = element.select("a").attr("title");
			catalogInfo.setUtime(title.substring(title.indexOf("：")+1, title.indexOf(" 章节字数")));
			catalogInfo.setCount(Integer.parseInt(title.substring(title.lastIndexOf("：")+1)));
			catalogInfo.setSort(i++); //章节排序
			catalogDao.insertCatalog(catalogInfo);
		}
	}
	/**
	 * 发起请求并获得返回值
	 * @author zhoumh
	 * @version 创建时间：2017年9月20日 下午3:07:32
	 */
	private String getHTML(String url) {
		String html = "";
		// 设置cookie
		requestConfig = RequestConfig.custom()
				.setConnectionRequestTimeout(10000).setConnectTimeout(10000)
				.setCookieSpec(CookieSpecs.STANDARD_STRICT)
				.build();
		try {
			// 生成一个httpclient对象
			httpClient = HttpClients.custom()
					.setDefaultRequestConfig(requestConfig)
					.build();
			// get请求接收返回信息
			CloseableHttpResponse response = doGet(httpClient, url);
			HttpEntity entity = response.getEntity();
			// 判断返回实体是否为空
			if (entity != null) {
				// 获取返回的内容
				html = EntityUtils.toString(entity, "UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 关闭或释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return html;
	}
	/**
	 * 根据传入的URL和httpclient发起get请求并返回结果
	 * @author zhoumh
	 * @version 创建时间：2017年7月26日 下午5:18:47
	 * @throws IOException
	 * @throws ClientProtocolException
	 */
	private CloseableHttpResponse doGet(CloseableHttpClient httpClient,
			String url) throws ClientProtocolException, IOException {
		HttpGet httpGet = new HttpGet(url);
		// 配置请求的HEADER部分
		httpGet.addHeader(HttpHeaders.ACCEPT, "application/xml");
		// 接收返回信息
		CloseableHttpResponse response = httpClient.execute(httpGet);
		return response;
	}
	/**
	 * 根据传入的URL和httpclient发起POST请求并返回结果
	 * @author zhoumh
	 * @version 创建时间：2017年7月26日 下午5:19:23
	 * @throws IOException
	 * @throws ClientProtocolException
	 */
	private CloseableHttpResponse doPost(CloseableHttpClient httpClient,
			String url, UrlEncodedFormEntity uefEntity)
			throws ClientProtocolException, IOException {
		// Post请求
		HttpPost httppost = new HttpPost(url);
		httppost.setEntity(uefEntity);
		// 发送请求并接收返回信息
		CloseableHttpResponse response = httpClient.execute(httppost);
		return response;
	}

}
